<?php
/**
 * Class Moimir_Client
 * @author Vasily Arnautov <epicgoods@gmail.com>
 */

class Moimir_Client {

    private $app_id, $secret_key, $return_url, $response, $uid, $access_token, $refresh_token;

    public function __construct($app_id, $secret_key, $return_url='', $access_token='', $refresh_token='') {
        $this->app_id =$app_id;
        $this->secret_key = $secret_key;
        $this->return_url = $return_url;
        $this->access_token = $access_token;
        $this->refresh_token = $refresh_token;
    }

    public function transport($url, array $params=array(), $method='post') {
        switch($method) {
            case 'post':
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, $url);
                curl_setopt($ch, CURLOPT_POST, 1);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $params);

                $this->response = curl_exec($ch);
                curl_close($ch);
                break;
            default:
                $this->response = null;
                break;
        }
        $data = json_decode($this->response,1);
        if (!is_array($data)) {
            throw new Exception('Error! Not formatted result from MoiMir.');
        } else if (isset($data['error']['error_msg'])) {
            throw new Exception('Error! MoiMir says: "'.$data['error']['error_msg'].'"');
        } else if (isset($data['error'])) {
            throw new Exception('Error! MoiMir says: "'.$data['error'].'"');
        } else {
            return $data;
        }
    }

    public function authenticate($code) {
        $params = array(
            'client_id' => $this->app_id,
            'client_secret'=> $this->secret_key,
            'grant_type' => 'authorization_code',
            'code' => $code,
            'redirect_uri'=>$this->return_url
        );
        $res = $this->transport('https://connect.mail.ru/oauth/token', $params);
        if (isset($res['refresh_token']))
            $this->refresh_token = $res['refresh_token'];
        if (isset($res['access_token']))
            $this->access_token = $res['access_token'];
        if (isset($res['x_mailru_vid']))
            $this->uid = $res['x_mailru_vid'];
    }

    public function getAccessToken() {
        return $this->access_token;
    }

    public function getRefreshToken() {
        return $this->refresh_token;
    }

    public function getUid() {
        return $this->uid;
    }

    public function getResponse() {
        return $this->response;
    }

    public function getAppId() {
        return $this->app_id;
    }

    public function execute($api_method, $params=array()) {
        $params['method'] = $api_method;
        $params['app_id'] = $this->app_id;
        $params['secure'] = 1;
        $params['session_key'] = $this->access_token;
        $params['sig'] = $this->sign_server_server($params);
        $res = $this->transport('http://www.appsmail.ru/platform/api', $params);
        return $res;
    }

    private function sign_server_server(array $request_params) {
        ksort($request_params);
        $params = '';
        foreach ($request_params as $key => $value) {
            $params .= "$key=$value";
        }
        return md5($params . $this->secret_key);
    }

    public function createAuthUrl($scope) {
        return 'https://connect.mail.ru/oauth/authorize?'.http_build_query(array(
            'client_id'=>$this->app_id,
            'response_type'=>'code',
            'scope'=>$scope,
            'redirect_uri'=>$this->return_url
        ));
    }

    public function refresh_token() {
        $params = array(
            'client_id' => $this->app_id,
            'client_secret'=> $this->secret_key,
            'grant_type' => 'refresh_token',
            'refresh_token'=> $this->refresh_token
        );
        $res = $this->transport('https://connect.mail.ru/oauth/token', $params);
        if (isset($res['refresh_token']))
            $this->refresh_token = $res['refresh_token'];
        if (isset($res['access_token']))
            $this->access_token = $res['access_token'];
        if (isset($res['x_mailru_vid']))
            $this->uid = $res['x_mailru_vid'];
    }
}